package de.lmu.ifi.pst.uwejsf.framework;

import java.util.regex.Matcher;
import java.util.regex.Pattern;

import javax.el.ELContext;
import javax.el.ValueExpression;
import javax.faces.application.Application;
import javax.faces.context.FacesContext;

public class ExpressionHelpers {
	public static Object resolveValue(String expression) {
		FacesContext context = FacesContext.getCurrentInstance();
		Application application = FacesContext.getCurrentInstance()
				.getApplication();
		Object value = application.evaluateExpressionGet(context, expression,
				Object.class);
		return value;
	}

	public static void setValue(String expression, Object value) {
		FacesContext context = FacesContext.getCurrentInstance();
		Application application = FacesContext.getCurrentInstance()
				.getApplication();
		ELContext elContext = context.getELContext();
		ValueExpression valueExpression = application.getExpressionFactory().createValueExpression(elContext,
				expression, Object.class);
		valueExpression.setValue(elContext, value);
	}
	
	
	
	
	
	public static String refineExpressionBody(String valueExpression,
			String prefix) {
		StringBuffer output = new StringBuffer();
		Pattern pattern = Pattern.compile("('.*?')");
		Matcher matcher = pattern.matcher(valueExpression);

		int i = 0;
		String workString = new String(valueExpression);
		while (matcher.find()) {
			i++;
			String quoted = matcher.group(1);
			String expressionPart = workString.substring(0, matcher.start(1));
			String refinedPart = refineExpressionPart(expressionPart,
					prefix);
			output.append(refinedPart).append(quoted);
			workString = workString.substring(matcher.end(1));
			matcher.reset(workString);

		}

		output.append(refineExpressionPart(workString, prefix));

		return output.toString();
	}

	private static String refineExpressionPart(String expressionPart,
			String prefix) {
		StringBuffer output = new StringBuffer();
		Pattern pattern = Pattern.compile("([a-zA-Z_]+[\\w\\d_\\.]*)");

		Matcher matcher = pattern.matcher(expressionPart);
		String workString = new String(expressionPart);
		int i = 0;
		while (matcher.find()) {
			i++;
			String token = matcher.group(1);
			String refinedToken = handleToken(token, prefix);
			output.append(workString.substring(0, matcher.start(1))).append(
					refinedToken);
			workString = workString.substring(matcher.end(1));
			matcher.reset(workString);

		}
		if (i == 0)
			return expressionPart;
		else
			output.append(workString);
		return output.toString();
	}

	private static String handleToken(String token, String prefix) {

		String output = new String(token);
		
	

		if (token.startsWith("self.")) {
			output = token.replaceFirst("self\\.", prefix);
		} else {
			output = prefix + token;
		
		}

		return output;
	}
	
	
	public static void main(String[] args) {
		System.out.println(refineExpressionBody("win == 'true'", "object_GuessNumber_"));
		System.out.println(refineExpressionBody("result = guess +42", "object_GuessNumber_"));
	}
}
